﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Web.Helper;
using Web.Models;
using RentalSystem.Data.EF;
using RentalSystem.Data.EF.Core;
using Web.Security;
using System.IO;

namespace Web.Controllers
{
    [Authorize(Roles = RoleType.Worker + "," + RoleType.Administrator)]
    public class WorkersController : BaseController
    {
        [HttpGet]
        public ActionResult Index()
        {
            return View();
        }

        [HttpGet]
        public ActionResult Events(int page = 1)
        {
            int pageSize = SettingsManager.SmallItemsCountOnPages;
            List<UserLogs> logsFromDb = DataContext.UserLogsDao.ListByUser(CurrentUser.Guid);

            LogsListViewModel model = new LogsListViewModel()
            {
                logs = logsFromDb.OrderByDescending(x => x.UserLogDate).Skip((page - 1) * pageSize).Take(pageSize).ToList(),
                PagingInfo = new PagingInfo(page, pageSize, logsFromDb.Count)
            };

            return View(model);
        }

        #region Locations

        [HttpGet]
        public ActionResult Locations(int page = 1)
        {
            int pageSize = SettingsManager.BigItemsCountOnPages;
            List<Agencies> agencies = DataContext.AgenciesDao.List();

            foreach (Agencies a in agencies)
            {
                if (a.AgencyName.Equals("Default"))
                {
                    agencies.Remove(a);
                    break;
                }
            }

            LocationListViewModel model = new LocationListViewModel
            {
                List = agencies.OrderBy(p => p.AgencyName).Skip((page - 1) * pageSize).Take(pageSize),
                PagingInfo = new PagingInfo(page, pageSize, agencies.Count)
            };

            LoadErrorsAndSuccessFromAnotherPage();
            SetFormMode(Mode.Edit);
            return View(model);
        }

        [HttpGet]
        public ActionResult LocationAdd()
        {
            SetFormMode(Mode.Create);
            return View();
        }

        [HttpPost]
        public ActionResult LocationAdd(Agencies agency, HttpPostedFileBase imageFile)
        {
            if (ModelState.IsValid)
            {
                try
                {
                    if (String.IsNullOrEmpty(agency.AgencyName) || String.IsNullOrEmpty(agency.AgencyAddress))
                    {
                        ModelState.AddModelError("", "Uzupełnij wszystkie pola!");
                        return View(agency);
                    }

                    agency.AgencyCreatedDate = DateTime.Now;
                    agency.AgencyIsActive = true;
                    agency.AgencyTypeID = 1;

                    if (imageFile == null)
                        ShowError("Nie wybrano zdjęcia - pamiętaj aby w przyszłości uzupełnić wygląd wideoteki!");
                    else
                    {
                        Files file = EntityManager.UploadImage(FileType.LocationImage, agency.AgencyName, imageFile, DataContext, Server);

                        if (file != null)
                        {
                            file = DataContext.FilesDao.Add(file);
                            agency.AgencyImageFileID = file.FileID;
                        }
                    }

                    DataContext.AgenciesDao.Add(agency);

                    agency.AgencyID = DataContext.AgenciesDao.GetIdByName(agency.AgencyName);
                    LogManager.WorkerCreateLocation(CurrentUser.Guid, String.Format("Agencja: {0}", agency.AgencyName));

                    ShowSuccess("Wideoteka została dodana!");
                    return View(agency);
                }
                catch (Exception exc)
                {
                    SetFormMode(Mode.Create);
                    ShowError(exc.Message);
                    return View(agency);
                }
            }

            SetFormMode(Mode.Create);
            return View(agency);
        }

        [HttpGet]
        public ActionResult LocationDelete(int id = 0)
        {
            try
            {
                EntityManager.DeleteLocation(id, DataContext, Server);
                LogManager.WorkerDeleteLocation(CurrentUser.Guid);
                return RedirectToAction("Locations");
            }
            catch (Exception exc)
            {
                ShowErrorOnAnotherPage(exc.Message);
                return RedirectToAction("Locations");
            }
        }

        [HttpPost]
        public ActionResult LocationUpdate(Agencies agency, HttpPostedFileBase imageFile)
        {
            if (ModelState.IsValid)
            {
                try
                {
                    if (String.IsNullOrEmpty(agency.AgencyName) || String.IsNullOrEmpty(agency.AgencyAddress))
                    {
                        ModelState.AddModelError("", "Uzupełnij wszystkie pola!");
                        return View(agency);
                    }

                    agency.AgencyTypeID = 1;

                    if (imageFile == null)
                        ShowError("Nie wybrano zdjęcia - pamiętaj aby w przyszłości uzupełnić wygląd wideoteki!");
                    else
                    {
                        Files file = EntityManager.UploadImage(FileType.LocationImage, agency.AgencyName, imageFile, DataContext, Server);

                        if (file != null)
                        {
                            file = DataContext.FilesDao.Add(file);
                            agency.AgencyImageFileID = file.FileID;
                        }
                    }

                    DataContext.AgenciesDao.Update(agency, (uint)AgencyFields.All);
                    LogManager.WorkerUpdateLocation(CurrentUser.Guid, String.Format("Agencja: {0}", agency.AgencyName));

                    ShowSuccessOnAnotherPage("Zmiany zostały zapisane!");
                    return RedirectToAction("Locations");
                }
                catch (Exception exc)
                {
                    SetFormMode(Mode.Edit);
                    ShowErrorOnAnotherPage(exc.Message);
                    return RedirectToAction("Locations");
                }
            }

            SetFormMode(Mode.Edit);
            ShowErrorOnAnotherPage("Niewłaściwe dane! Zmiany nie zostały zapisane");
            return RedirectToAction("Locations");
        }

        #endregion

        #region Users

        [HttpGet]
        public ActionResult Users(int page = 1)
        {
            List<Users> users = DataContext.UsersDao.List();

            if (users != null)
            {
                for (int i = users.Count - 1; i >= 0; i--)
                {
                    if (users[i].UserRoleID == 3)
                        users.RemoveAt(i);
                }

                UserListViewModel model = new UserListViewModel()
                {
                    Users = users.OrderByDescending(x => x.UserRoleID).ToList(),
                    PagingInfo = new PagingInfo(page, SettingsManager.SmallItemsCountOnPages, users.Count)
                };

                return View(model);
            }

            LoadErrorsAndSuccessFromAnotherPage();
            return View();
        }

        [HttpGet]
        public ActionResult UserEdit(string userGuid)
        {
            Users user = DataContext.UsersDao.Get(userGuid);

            if (user == null)
            {
                ShowError("Nie odnaleziono użytkownika");
                return View();
            }

            RegistryData model = new RegistryData
            {
                User = user,
                Customer = user.Customers,
                Person = user.Customers.Persons
            };

            if (user.UserRoleID != 1) model.IsWorker = true;

            return View(model);
        }

        [HttpPost]
        public ActionResult UserEdit(string userGuid, RegistryData model)
        {
            if (model != null)
            {
                if (!string.IsNullOrEmpty(model.Password))
                    model.User.UserPassword = Helper.Crypto.ComputeMD5(model.Password);
                if (model.User.AgencyId == 0)
                    model.User.AgencyId = 1;

                Users different = DataContext.UsersDao.GetByEmail(model.User.UserEmail);

                if (different != null && different.UserGuid != model.User.UserGuid)
                {
                    ShowError("Adres email jest przypisany do innego użytkownika!");
                    return View(model);
                }

                DataContext.UsersDao.Update(model.User, (uint)UserFields.All);
                DataContext.PersonsDao.Update(model.Person, (uint)PersonFields.All);
                LogManager.WorkerEditUser(CurrentUser.Guid, String.Format("Edycja użytkownika: ", model.User.UserDisplayName));
                ShowSuccess("Zmiany zostały zapisane");
            }
            else
            {
                ShowError("Zmiany nie zostały zapisane!");
            }

            return View(model);
        }

        [HttpGet]
        public ActionResult UserDelete(string userGuid)
        {
            //try
            //{
            //    Users user = DataContext.UsersDao.Get(userGuid);

            //    if (user == null)
            //    {
            //        ShowErrorOnAnotherPage("Nie odnaleziono użytkownika");
            //        return RedirectToAction("Users");
            //    }

            //    EntityManager.DeleteUser(userGuid);
            //    ShowSuccessOnAnotherPage("Usunięto użytkownika!");
            //}
            //catch (Exception exc)
            //{
            //    ShowErrorOnAnotherPage(exc.Message);
            //}

            ShowErrorOnAnotherPage("Nie ma możliwości usuwania użytkowników! Aby wyeliminować użytkownika z systemu zmień jego aktywnośćna stronie edycji");
            return RedirectToAction("Users");
        }

        [HttpGet]
        [Authorize(Roles = RoleType.Administrator)]
        public ActionResult NewEmployee()
        {
            RegistryData model = new RegistryData()
            {
                IsWorker = true
            };
            return View(model);
        }

        [HttpPost]
        [Authorize(Roles = RoleType.Administrator)]
        public ActionResult NewEmployee(RegistryData model)
        {
            try
            {
                if (ModelState.IsValid)
                {
                    model.Customer = new Customers();
                    model.Customer.Persons = model.Person;
                    model.User.Customers = model.Customer;

                    string error = EntityManager.ValidateNewUser(model.User);
                    if (!String.IsNullOrEmpty(error))
                    {
                        ModelState.AddModelError("", error);
                        return View(model);
                    }

                    if (string.IsNullOrEmpty(model.Password)) model.Password = Helper.Helper.GenerateRandomPassword(5);

                    Users newUser = EntityManager.FillDefaultUserData(model.User, model.Password, UserRolesTypes.Worker);

                    this.DataContext.UsersDao.Add(newUser);
                    LogManager.UserRegistered(newUser.UserGuid);
                    LogManager.WorkerAddUser(CurrentUser.Guid, string.Format("Użytkownik: ", model.User.UserDisplayName));
                    ShowSuccess(String.Format("Utworzono użytkownika. Dane do logowania: Login={0}, Hasło={1}", model.User.UserEmail, model.Password));
                }
            }
            catch (Exception exc)
            {
                ShowError(exc.Message);
            }
            return View(model);
        }

        #endregion

        #region Rents

        [HttpGet]
        public ActionResult CurrentHires(int page = 1)
        {
            int pageSize = SettingsManager.BigItemsCountOnPages;
            List<Hires> currentHires = DataContext.HiresDao.ListCurrentHires();

            MovieHiresListViewModel model = new MovieHiresListViewModel()
            {
                Hires = currentHires.OrderBy(x => x.HirePlanningReturningDate).Skip((page - 1) * pageSize).Take(pageSize),
                PagingInfo = new PagingInfo(page, pageSize, currentHires.Count)
            };

            LoadErrorsAndSuccessFromAnotherPage();
            return View(model);
        }

        [HttpPost]
        public ActionResult CurrentHires(MovieHiresListViewModel model, int page = 1)
        {
            int pageSize = SettingsManager.BigItemsCountOnPages;
            List<Hires> currentHires = DataContext.HiresDao.ListCurrentHires();

            if (currentHires != null && currentHires.Count > 0)
            {
                List<Hires> filtered = new List<Hires>();

                foreach (Hires hire in currentHires)
                {
                    if (!string.IsNullOrEmpty(model.MovieTitle))
                    {
                        if (!hire.Discs.Movies.MovieTitle.ToLower().Contains(model.MovieTitle.ToLower())) continue;
                    }
                    if (!string.IsNullOrEmpty(model.CustomerName))
                    {
                        if (!hire.Users.UserDisplayName.ToLower().Contains(model.CustomerName.ToLower())
                            && !hire.Users.Customers.Persons.PersonFirstName.ToLower().Contains(model.CustomerName.ToLower())
                            && !hire.Users.Customers.Persons.PersonLastName.ToLower().Contains(model.CustomerName.ToLower()))
                            continue;
                    }
                    filtered.Add(hire);
                }
                currentHires = filtered;
            }

            model.Hires = currentHires.OrderBy(x => x.HirePlanningReturningDate).Skip((page - 1) * pageSize).Take(pageSize);
            model.PagingInfo = new PagingInfo(page, pageSize, currentHires.Count);

            return View(model);
        }

        [HttpGet]
        public ActionResult AllHires(int page = 1)
        {
            int pageSize = SettingsManager.BigItemsCountOnPages;
            List<Hires> hires = DataContext.HiresDao.List().OrderByDescending(x => x.HireSignupDate).ToList();

            MovieHiresListViewModel model = new MovieHiresListViewModel()
            {
                Hires = hires.Skip((page - 1) * pageSize).Take(pageSize),
                PagingInfo = new PagingInfo(page, pageSize, hires.Count)
            };

            return View(model);
        }

        [HttpPost]
        public ActionResult AllHires(MovieHiresListViewModel model, int page = 1)
        {
            int pageSize = SettingsManager.BigItemsCountOnPages;
            List<Hires> hires = DataContext.HiresDao.List();

            if (hires != null && hires.Count > 0)
            {
                List<Hires> filtered = new List<Hires>();

                foreach (Hires hire in hires)
                {
                    if (!string.IsNullOrEmpty(model.MovieTitle))
                    {
                        if (!hire.Discs.Movies.MovieTitle.ToLower().Contains(model.MovieTitle.ToLower())) continue;
                    }
                    if (!string.IsNullOrEmpty(model.CustomerName))
                    {
                        if (!hire.Users.UserDisplayName.ToLower().Contains(model.CustomerName.ToLower())
                            && !hire.Users.Customers.Persons.PersonFirstName.ToLower().Contains(model.CustomerName.ToLower())
                            && !hire.Users.Customers.Persons.PersonLastName.ToLower().Contains(model.CustomerName.ToLower()))
                            continue;
                    }
                    filtered.Add(hire);
                }
                hires = filtered.OrderByDescending(x => x.HireSignupDate).Skip((page - 1) * pageSize).Take(pageSize).ToList();
            }
            return View(model);
        }

        [HttpGet]
        public ActionResult ReturnHiredDisc(string hireGuid)
        {
            try
            {
                Hires hire = DataContext.HiresDao.Get(hireGuid);
                string message = EntityManager.ReturnHiredMovie(hireGuid, SettingsManager);
                LogManager.WorkerReceiveReturnMovie(CurrentUser.Guid, String.Format("Zwrot filmu {0} wypożyczonego przez {1}", hire.Discs.Movies.MovieTitle, hire.Users.UserDisplayName));
                LogManager.CustomerReturnMovie(hire.UserGuid, String.Format("Zwrot filmu {0}", hire.Discs.Movies.MovieTitle));
                ShowSuccessOnAnotherPage(message);
            }
            catch (Exception exc)
            {
                ShowErrorOnAnotherPage(exc.Message);
            }
            return RedirectToAction("CurrentHires");
        }

        [HttpGet]
        public ActionResult Finances(int page = 1)
        {
            int pageSize = SettingsManager.BigItemsCountOnPages;
            List<Hires> hires = DataContext.HiresDao.List().OrderByDescending(x => x.HireSignupDate).ToList();

            Dictionary<Agencies, float> locationsProfits = new Dictionary<Agencies, float>();
            List<string> messages = new List<string>();

            List<Agencies> agencies = DataContext.AgenciesDao.List();
            Hires bestHire = null;
            float higherCost = 0;
            float allProfits = 0;

            if (agencies != null && agencies.Count > 0)
            {
                foreach (Agencies agency in agencies)
                {
                    if (agency.AgencyName == "Default") continue;

                    float profits = 0;

                    foreach (Discs disc in agency.Discs)
                    {
                        foreach (Hires hire in disc.Hires)
                        {
                            float cost = (float)(hire.HirePlanningCost + hire.HireLateReward);
                            profits += cost;

                            if (cost > higherCost) { bestHire = hire; higherCost = cost; }
                        }
                    }

                    allProfits += profits;
                    locationsProfits.Add(agency, profits);
                }
            }


            if (allProfits > 0)
            {
                messages.Add(String.Format("Całkowity zysk wypożyczalni to {0:0.00}zł", allProfits));
            }
            if (higherCost > 0)
            {
                messages.Add(String.Format("Najdroższe wypożyczenie({0} na nośniku {1}) o wartości {2:0.00}zł odnotowano w wypożyczalni {3} dnia {4}r",
                    bestHire.Discs.Movies.MovieTitle, bestHire.Discs.DiscTypes.DiscTypeName, higherCost, bestHire.Discs.Agencies.AgencyName, bestHire.HireSignupDate.ToString("dd.MM.yyyy")));
            }

            FinancesViewModel model = new FinancesViewModel()
            {
                Hires = hires.Skip((page - 1) * pageSize).Take(pageSize).ToList(),
                LocationsProfits = locationsProfits,
                Messages = messages,
                PagingInfo = new PagingInfo(page, pageSize, hires.Count)
            };

            return View(model);
        }

        #endregion

        #region Movies

        [HttpGet]
        public ActionResult Movies(ListItemType itemType = ListItemType.Small, int page = 1)
        {
            int pageSize = 10;
            if (itemType == ListItemType.Small)
                pageSize = 30;

            List<MovieViewModel> movies = EntityManager.TranslateMoviesObject(DataContext.MoviesDao.List());

            MovieListViewModel model = new MovieListViewModel
            {
                movies = movies.OrderBy(m => m.Movie.MovieTitle).Skip((page - 1) * pageSize).Take(pageSize),
                PagingInfo = new PagingInfo(page, pageSize, movies.Count),
                Size = MovieListViewModel.SizeSmall
            };

            LoadErrorsAndSuccessFromAnotherPage();

            return View(model);
        }

        [HttpGet]
        public ActionResult MovieAdd()
        {
            MovieViewModel movie = EntityManager.ChangeMovieObject(DataContext.MoviesDao.Get(""));
            SetFormMode(Mode.Create);
            return View("MovieEdit", movie);
        }

        [HttpPost]
        public ActionResult MovieAdd(MovieViewModel model, HttpPostedFileBase imageFile)
        {
            try
            {
                model.Movie.MovieGuid = Helper.Helper.GenerateGuid();

                if (imageFile != null)
                {
                    Files file = EntityManager.UploadImage(FileType.MovieImage, model.Movie.MovieGuid, imageFile, DataContext, Server);

                    if (file != null)
                    {
                        //file = DataContext.FilesDao.Add(file);
                        model.Movie.Files = file;
                    }
                }

                Movies otherEntity = DataContext.MoviesDao.GetByTitle(model.Movie.MovieTitle);

                if (otherEntity != null && otherEntity.MovieGuid != model.Movie.MovieGuid)
                {
                    ShowError("Podany film występuje w bazie");
                }

                DataContext.MoviesDao.Add(model.Movie);
                EntityManager.UpdateMovieMovieKinds(model, DataContext);
                LogManager.WorkerCreateMovie(CurrentUser.Guid, String.Format("Nowy film: {0}", model.Movie.MovieTitle));
                EntityManager.UpdateStatsNewMovie(model.Movie.MovieDuration);
                ShowSuccess("Film dodano poprawnie");
            }
            catch (Exception exc)
            {
                ShowError(exc.Message);
            }
            SetFormMode(Mode.Display);
            return View("MovieEdit", model);
        }

        [HttpGet]
        public ActionResult MovieEdit(string guid)
        {
            MovieViewModel movie = EntityManager.ChangeMovieObject(DataContext.MoviesDao.Get(guid));

            SetFormMode(Mode.Edit);
            return View(movie);
        }

        [HttpPost]
        public ActionResult MovieEdit(MovieViewModel model, HttpPostedFileBase imageFile)
        {
            try
            {
                if (imageFile != null)
                {
                    Files file = EntityManager.UploadImage(FileType.MovieImage, model.Movie.MovieGuid, imageFile, DataContext, Server);

                    if (file != null)
                    {
                        file = DataContext.FilesDao.Add(file);
                        model.Movie.MovieImageFileID = file.FileID;
                    }
                }

                Movies otherEntity = DataContext.MoviesDao.GetByTitle(model.Movie.MovieTitle);

                if (otherEntity != null && otherEntity.MovieGuid != model.Movie.MovieGuid)
                {
                    ShowError("Podany film występuje w bazie");
                }

                DataContext.MoviesDao.Update(model.Movie, (uint)MovieFields.All);
                EntityManager.UpdateMovieMovieKinds(model, DataContext);
                LogManager.WorkerUpdateMovie(CurrentUser.Guid, String.Format("Edycja filmu: {0}", model.Movie.MovieTitle));
                model.Movie = DataContext.MoviesDao.Get(model.Movie.MovieGuid);
                ShowSuccess("Zapisano zmiany");
            }
            catch (Exception exc)
            {
                ShowError(exc.Message);
            }
            SetFormMode(Mode.Display);
            return View("MovieEdit", model);
        }

        [HttpGet]
        public ActionResult MovieDelete(string guid)
        {
            try
            {
                Movies movie = DataContext.MoviesDao.Get(guid);
                if (movie != null && movie.Files != null && movie.Files.FileUrl != null)
                    EntityManager.DeleteFileIfExist(movie.Files.FileUrl, DataContext, Server);
                EntityManager.DeleteMovie(movie);
                EntityManager.UpdateStatsNewMovie(-movie.MovieDuration);
                LogManager.WorkerDeleteMovie(CurrentUser.Guid);
                ShowSuccessOnAnotherPage("Usunięto film " + movie.MovieTitle);
            }
            catch (Exception exc)
            {
                ShowErrorOnAnotherPage(exc.Message);
            }

            return RedirectToAction("Movies");
        }

        #region Movie Categories

        [HttpGet]
        [Authorize(Roles = RoleType.Administrator)]
        public ActionResult MoviesCategories()
        {
            LoadErrorsAndSuccessFromAnotherPage();
            List<MovieKinds> list = DataContext.MovieKindsDao.List();
            list.OrderBy(x => x.MovieKindName);
            return View(list);
        }

        [HttpGet]
        [Authorize(Roles = RoleType.Administrator)]
        public ActionResult MoviesCategoryAdd()
        {
            SetFormMode(Mode.Create);
            return View("MoviesCategoryEdit");
        }

        [HttpPost]
        [Authorize(Roles = RoleType.Administrator)]
        public ActionResult MoviesCategoryAdd(MovieKinds model)
        {
            if (ModelState.IsValid)
            {
                try
                {
                    if (String.IsNullOrEmpty(model.MovieKindName) || string.IsNullOrEmpty(model.MovieKindShortcut))
                    {
                        SetFormMode(Mode.Edit);
                        ShowError("Niepoprawnie uzupełnione dane");
                        return View("MoviesCategoryEdit");
                    }

                    if (DataContext.MovieKindsDao.GetByName(model.MovieKindName) != null)
                    {
                        SetFormMode(Mode.Edit);
                        ShowError("Podana kategoria występuje w bazie");
                        return View("MoviesCategoryEdit");
                    }

                    DataContext.MovieKindsDao.Add(model);
                    LogManager.WorkerEditMovieCategories(CurrentUser.Guid);
                    ShowSuccess("Kategoria filmu została dodana poprawnie");
                }
                catch (Exception exc)
                {
                    SetFormMode(Mode.Edit);
                    ShowError(exc.Message);
                }
            }

            return View("MoviesCategoryEdit");
        }

        [HttpGet]
        [Authorize(Roles = RoleType.Administrator)]
        public ActionResult MoviesCategoryEdit(int id)
        {
            MovieKinds mk = DataContext.MovieKindsDao.Get(id);
            SetFormMode(Mode.Edit);
            return View(mk);
        }

        [HttpPost]
        [Authorize(Roles = RoleType.Administrator)]
        public ActionResult MoviesCategoryEdit(MovieKinds model)
        {
            if (ModelState.IsValid)
            {
                try
                {
                    if (String.IsNullOrEmpty(model.MovieKindName) || string.IsNullOrEmpty(model.MovieKindShortcut))
                    {
                        SetFormMode(Mode.Edit);
                        ShowError("Niepoprawnie uzupełnione dane");
                        return View("MoviesCategoryEdit");
                    }

                    MovieKinds old = DataContext.MovieKindsDao.GetByName(model.MovieKindName);

                    if (old != null && old.MovieKindID != model.MovieKindID)
                    {
                        SetFormMode(Mode.Edit);
                        ShowError("Podana kategoria występuje w bazie");
                        return View();
                    }

                    DataContext.MovieKindsDao.Update(model, (uint)MovieKindFields.All);
                    LogManager.WorkerEditMovieCategories(CurrentUser.Guid);
                    ShowSuccess("Zmiany zostały zapisane");
                }
                catch (Exception exc)
                {
                    SetFormMode(Mode.Edit);
                    ShowError(exc.Message);
                }
            }

            return View();
        }

        [HttpGet]
        [Authorize(Roles = RoleType.Administrator)]
        public ActionResult MoviesCategoryDelete(int id)
        {
            try
            {
                DataContext.MovieKindsDao.Delete(id);
                LogManager.WorkerEditMovieCategories(CurrentUser.Guid);
                ShowSuccessOnAnotherPage("Kategoria została usunięta. Przypisane do niej filmy zostały zmodyfikowane!");
                return RedirectToAction("MoviesCategories");
            }
            catch (Exception exc)
            {
                ShowErrorOnAnotherPage(exc.Message);
                return RedirectToAction("MoviesCategories");
            }
        }

        #endregion

        #region MovieCopies
        [HttpGet]
        public ActionResult MovieCopies(string guid)
        {
            Movies movie = DataContext.MoviesDao.Get(guid);
            List<Agencies> agencies = DataContext.AgenciesDao.List();

            if (movie == null || agencies == null)
            {
                ShowError("Błąd parametrów");
                return View();
            }

            if (agencies.Count == 0)
            {
                ShowError("Aby wprowadzić kopie filmu stwórz przynajmniej 1 agencję!");
                return View();
            }

            Dictionary<Agencies, int> copies = new Dictionary<Agencies, int>();
            foreach (Agencies agency in agencies)
            {
                if (agency.AgencyName == "Default") continue;

                int movieDiscCount = 0;

                foreach (Discs disc in agency.Discs)
                {
                    if (disc.MovieGuid == guid)
                        movieDiscCount++;
                }

                copies.Add(agency, movieDiscCount);
            }
            return View(new MovieCopiesListViewModel() { Movie = movie, Copies = copies });
        }

        [HttpGet]
        public ActionResult MovieCopiesInLocation(string guid, int agencyId)
        {
            if (string.IsNullOrEmpty(guid) || agencyId == 0)
            {
                ShowError("Nie odnaleziono kopii dla podanego filmu w wybranej agencji!");
                return View();
            }

            Movies movie = DataContext.MoviesDao.Get(guid);
            Agencies agency = DataContext.AgenciesDao.Get(agencyId);

            if (movie == null || agency == null)
            {
                ShowError("Nie odnaleziono kopii dla podanego filmu w wybranej agencji!");
                return View();
            }

            List<Discs> discs = DataContext.DiscsDao.ListMovieDiscFromAgency(guid, agencyId);

            MovieLocationCopiesViewModel model = new MovieLocationCopiesViewModel()
            {
                Movie = movie,
                Agency = agency,
                Copies = discs,
                NewCdItemPerCopy = 1,
                NewDvdItemPerCopy = 1,
                NewBlueRayItemPerCopy = 1,
                NewHdDvdItemPerCopy = 1,
            };

            LoadErrorsAndSuccessFromAnotherPage();
            return View(model);
        }

        [HttpPost]
        public ActionResult MovieCopiesInLocation(string guid, int agencyId, MovieLocationCopiesViewModel model)
        {
            Movies movie = DataContext.MoviesDao.Get(guid);
            Agencies agency = DataContext.AgenciesDao.Get(agencyId);

            if (movie == null || agency == null)
            {
                ShowError("Błędne dane! Nie wprowadzono zmian...");
                return View();
            }

            EntityManager.AddCopies(DiscType.CD, model.NewCdCopies, model.NewCdItemPerCopy, movie, agency);
            EntityManager.AddCopies(DiscType.DVD, model.NewDvdCopies, model.NewDvdItemPerCopy, movie, agency);
            EntityManager.AddCopies(DiscType.BlueRay, model.NewBlueRayCopies, model.NewBlueRayItemPerCopy, movie, agency);
            EntityManager.AddCopies(DiscType.HDDVD, model.NewHdDvdCopies, model.NewHdDvdItemPerCopy, movie, agency);

            LogManager.WorkerEditMovieDiscs(CurrentUser.Guid, agency.AgencyName);
            ShowSuccessOnAnotherPage("Zapisano zmiany!");
            return RedirectToAction("MovieCopiesInLocation", new { guid = guid, agencyId = agencyId });
        }

        [HttpGet]
        public ActionResult MovieCopiesInLocationDoAction(string guid, int agencyId, string discGuid, string actionType = "activate")
        {
            Discs disc = DataContext.DiscsDao.Get(discGuid);

            if (disc == null)
            {
                ShowErrorOnAnotherPage("Nie odnaleziono kopii filmu");
                return RedirectToAction("MovieCopiesInLocation", new { guid = guid, agencyId = agencyId });
            }

            switch (actionType)
            {
                case "activate": disc.DiscIsAvailable = !disc.DiscIsAvailable;
                    DataContext.DiscsDao.Update(disc, (uint)DiscFields.IsAvailable);
                    break;
                case "delete": EntityManager.DeleteDisc(disc);
                    break;
            }

            LogManager.WorkerEditMovieDiscs(CurrentUser.Guid, disc.Agencies.AgencyName);
            ShowSuccessOnAnotherPage("Wykonano akcję!");
            return RedirectToAction("MovieCopiesInLocation", new { guid = guid, agencyId = agencyId });
        }

        #endregion

        #endregion

        #region Pages contents

        [HttpGet]
        [Authorize(Roles = RoleType.Administrator)]
        public ActionResult EditContact()
        {
            PagesContents content = DataContext.PagesContentsDao.GetContentByTitle("ContactPage");
            PageContentData model = new PageContentData();

            if (content != null)
                model = new PageContentData { Id = content.PagesContentID, Content = content.PagesContentContent };

            return View(model);
        }

        [HttpGet]
        [Authorize(Roles = RoleType.Administrator)]
        public ActionResult EditPromotions()
        {
            PagesContents content = DataContext.PagesContentsDao.GetContentByTitle("DiscountsPage");
            PageContentData model = new PageContentData();

            if (content != null)
                model = new PageContentData { Id = content.PagesContentID, Content = content.PagesContentContent };

            return View(model);
        }

        [HttpGet]
        [Authorize(Roles = RoleType.Administrator)]
        public ActionResult EditRules()
        {
            PagesContents content = DataContext.PagesContentsDao.GetContentByTitle("RulesPage");
            PageContentData model = new PageContentData();

            if (content != null)
                model = new PageContentData { Id = content.PagesContentID, Content = content.PagesContentContent };

            return View(model);
        }

        [HttpPost, ValidateInput(false)]
        public ActionResult EditContact(PageContentData model)
        {
            LogManager.WorkerEditPageContent_Contact(CurrentUser.Guid);
            return SetPageContent(model, "ContactPage");
        }

        [HttpPost, ValidateInput(false)]
        public ActionResult EditPromotions(PageContentData model)
        {
            LogManager.WorkerEditPageContent_Discounts(CurrentUser.Guid);
            return SetPageContent(model, "DiscountsPage");
        }

        [HttpPost, ValidateInput(false)]
        public ActionResult EditRules(PageContentData model)
        {
            LogManager.WorkerEditPageContent_Rules(CurrentUser.Guid);
            return SetPageContent(model, "RulesPage");
        }

        private ActionResult SetPageContent(PageContentData model, string key)
        {
            if (ModelState.IsValid)
            {
                try
                {
                    if (string.IsNullOrEmpty(model.Content))
                    {
                        ModelState.AddModelError("", "Zawartość nie może być pusta!");
                        return View(model);
                    }

                    PagesContents pc = new PagesContents { PagesContentID = model.Id, PagesContentContent = model.Content, PagesContentTitle = key };
                    DataContext.PagesContentsDao.Update(pc, (uint)PagesContentFields.Content);
                    ViewBag.ActionResult = "Zmiany zostały zapisane!";
                    return View();
                }
                catch (Exception exc)
                {
                    ModelState.AddModelError("", exc.Message);
                    return View(model);
                }
            }

            ModelState.AddModelError("", "Błąd walidacji!");
            return View(model);
        }

        [HttpGet]
        [Authorize(Roles = RoleType.Administrator)]
        public ActionResult EditSettings()
        {
            SettingsViewModel settings = new SettingsViewModel()
            {
                BigItemsCountOnPages = SettingsManager.BigItemsCountOnPages.ToString(),
                HireLateRewardPerDay = SettingsManager.HireLateRewardPerDay.ToString(),
                HirePricePerDay = SettingsManager.HirePricePerDay.ToString(),
                HiresCountPerOneCustomer = SettingsManager.HiresCountPerOneCustomer.ToString(),
                HiresCountToNextLevel = SettingsManager.HiresCountToNextLevel.ToString(),
                HireTimeInDay = SettingsManager.HireTimeInDay.ToString(),
                SmallItemsCountOnPages = SettingsManager.SmallItemsCountOnPages.ToString(),
                UserDiscountPerLevelInPercentage = SettingsManager.UserDiscountPerLevelInPercentage.ToString()
            };

            LoadErrorsAndSuccessFromAnotherPage();
            return View(settings);
        }

        [HttpPost]
        [Authorize(Roles = RoleType.Administrator)]
        public ActionResult EditSettings(SettingsViewModel model)
        {
            try
            {
                if (model == null)
                {
                    ShowErrorOnAnotherPage("Niewłaściwe dane");
                    return RedirectToAction("EditSettings");
                }

                SettingsManager.BigItemsCountOnPages = int.Parse(model.BigItemsCountOnPages);
                SettingsManager.HireLateRewardPerDay = float.Parse(model.HireLateRewardPerDay);
                SettingsManager.HirePricePerDay = float.Parse(model.HirePricePerDay);
                SettingsManager.HiresCountPerOneCustomer = int.Parse(model.HiresCountPerOneCustomer);
                SettingsManager.HiresCountToNextLevel = int.Parse(model.HiresCountToNextLevel);
                SettingsManager.HireTimeInDay = int.Parse(model.HireTimeInDay);
                SettingsManager.SmallItemsCountOnPages = int.Parse(model.SmallItemsCountOnPages);
                SettingsManager.UserDiscountPerLevelInPercentage = int.Parse(model.UserDiscountPerLevelInPercentage);

                ShowSuccessOnAnotherPage("Zapisano zmiany!");
            }
            catch (Exception exc)
            {
                ShowErrorOnAnotherPage("Dane są nieprawidłowe! Nie zapisano zmian");
            }

            return RedirectToAction("EditSettings");
        }

        #endregion
    }
}
